home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
132_01
/
canew.c
< prev
next >
Wrap
Text File
|
1985-08-19
|
21KB
|
856 lines
/* Starting module of Tiny c compiler by Ron Cain */
/* Modified Feb. 10,1981 per P.L. Woods article in DDJ #52 */
/* Functions newfunc and getarg(t) affected */
/*
DEC 25,1981 repaired break function, module ca.c
May 5,1982 Modified declloc(typ) not to update the
the stack until all allocations have been performed . See
Doctor Dobb's #67 (May, 1982) in the letters column.
July 10,1982 Re-repaired break function. Use of "==" instead
of "=" in "ptr = readwhile() " if statement was problem.
July 13,1982 Changed stack offset in getarg(t) for character
variable from 0 to +1 due to byte swap between 8080 and 6809
machines.
*/
/* Other modules are CDEF.C Definitions */
/* CB.C Midsection of compiler */
/* CD.C End section of compiler */
#INCLUDE CDEF.H
/* */
/* */
/* Start CC1 */
/* */
/* Compiler begins execution here */
/* */
main()
{
glbptr =startglb; /* clear global symbols */
locptr=startloc; /* clear local symbols */
wqptr=wq; /* clear while queue */
macptr= /* clear the macro pool */
litptr= /* clear the literal pool*/
sp = /* stack ptr (relative) */
errcnt= /* no errors (yet) */
eof = /* not end of file */
input = /* no input file */
input2 = /* or include file */
output = /* no open units */
ncmp = /* no open compound stmt*/
lastst = /* no last statement */
quote[1]=
0; /* all set = to zero */
quote[0]='"'; /* fake a quote literal */
cmode=1; /* enable preprocessing */
/* */
/* Compile body */
/* */
ask(); /* get user options */
openout(); /* get an output file */
openin(); /* and initial input file */
header(); /* intro code */
parse(); /* process all input */
dumplits(); /* dump literal pool */
dumpglbs(); /* and all static memory*/
inclrn(); /* Bring in the run time package */
errorsummary(); /* summarize errors */
trailer(); /* follow-up code */
closeout(); /* close the output file (if any) */
return ; /* exit to system */
}
/* Process all input text */
/* */
/* At this level, only static declarations,defines,includes, */
/* and function definitions are legal... */
parse()
{
while (eof==0) /* do until no more input */
{
if(amatch("char",4)){declglb(cchar);ns();}
else if(amatch("int",3)){declglb(cint);ns();}
else if(match("#ASM"))doasm();
else if(match("#INCLUDE")) doinclude();
else if(match("#DEFINE"))addmac();
else newfunc();
blanks(); /*force eof if pending */
}
}
/* */
/* Dump the literal pool */
/* */
dumplits()
{
int j,k;
if (litptr==0) return; /* if nothing there, exit. */
printlabel(litlab);col(); /* print literal label */
k=0; /* init an index ... */
while (k<litptr) /* to loop with */
{
defbyte(); /* pseudo-op to define byte */
j=10; /* max bytes per line */
while(j--)
{
outdec((litq[k++]&127));
if ((j==0) || (k>=litptr))
{
nl(); /* need carriage return */
break;
}
outbyte (','); /* separate bytes */
}
}
}
/* Dump all static variables */
/* */
/* */
dumpglbs()
{
int j;
if (glbflag==0) return; /* no dump if user said no */
cptr=startglb;
while(cptr<glbptr) {
if (cptr[ident]!=function)
/* do if anything but function */
{ outstr(cptr);col(); /* output name as label..*/
defstorage(); /* define storage */
j=((cptr[offset]&255)+((cptr[offset+1]&255)<<8)); /* calculate number of bytes */
if ((cptr[type]==cint)||(cptr[ident]==pointer))
j=j+j;
outdec(j); /* neeed that many bytes */
nl();
}
cptr=cptr+symsiz;
}
}
/* */
/* Report errors to user */
/* */
errorsummary()
{ /* see if anything left hanging */
if (ncmp) error ("missing closing bracket");
/* Open compound statment */
nl();
comment();
outdec(errcnt); /* total number of errors */
outstr (" errors in compilation.");
nl();
}
/* */
/* Get options from user */
/* */
ask()
{
int k,num[1];
kill(); /* clear input line */
outbyte(12); /* clear the screen */
nl();nl();nl(); /* print banner */
pl(" small c compiler by Ron Cain ");
nl();
/* see if the user wants to interleave the c text */
/* in the form of comments for clarity. */
pl("Do you want the c-text to appear?");
gets(line); /*retreive answere */
ctext=0; /* assume no */
if ((ch()=='Y')||(ch()=='y'))
ctext =1; /* user said yes */
/* see if the user wants to allocate static variables by name in this module */
pl(" Do you want the globals to be defined? ");
gets(line);
glbflag=0;
if((ch()=='Y'||ch()=='y'))
glbflag = 1;
/* get the first allowable number for compiler-generated labels */
while(1)
{pl(" Starting number for labels?" );
gets(line);
if(ch()==0) {num[0]=0; break;}
if(k=number(num)) break;
}
nxtlab=num[0];
litlab=getlabel(); /* first label = literal pool */
kill(); /* erase line */
}
/* */
/* Get output file name */
/* */
openout()
{
char *ioptr;
kill(); /* erase line */
output = 0; /* start with none */
pl("Output filename?"); /* ask .... */
gets(line); /* get filename */
if(ch()==0)return; /* none given */
ioptr=line; /* copy of line pointer */
if((output=fcreat(line,iobuf0))==EOF) /* if given, open it up */
{output =0; /* cannot open file */
error(" Open failure ");
}
kill(); /* erase line */
}
/* */
/* Get (next) input file */
/* */
openin()
{
char *testptr;
input=0; /* none to start with */
while (input==0) /* any above 1 allowed */
{kill(); /* clear any line */
if(eof)break; /* if user said none */
pl("Input filename?");
gets(line);
testptr=line;
if(ch()==0){eof=1;break;} /* none given ... */
if((input=fopen(line,iobuf1))==EOF)
{input=0; /* cannot open it */
pl ("Open failure");
}
}
kill(); /* erase line */
}
/* */
/* Open an include file */
/* */
doinclude()
{blanks(); /* skip over to name */
if((input2=fopen(line+lptr,iobuf2))==EOF) {
input2=0;
error("Open failure on include file");
}
kill(); /* clear rest of line */
/* so next read will come from new file (if open) */
}
/* Close the output file */
closeout()
{if(output){fflush(iobuf0);fclose(iobuf0);}; /* if open,close it */
output=0; /* and mark it closed */
}
/* */
/* Declare a static variable (ie, define it for use) */
/* Makes an entry in the symbol table so subsequent references can call symbol by name */
/* */
declglb(typ)
int typ;
{
int k,j;
char sname[namesize];
while(1)
{while(1)
{if(endst())return; /* do line */
k=1; /* assume one element */
if(match("*")) /* pointer ? */
j=pointer; /* yes */
else j=variable; /* not a pointer*/
if(symname(sname)==0) /* name ok ? */
illname(); /* illegal name */
if(findglb(sname)) /* already there? */
multidef(sname);/* multiple def.*/
if(match("[")) /* array ? */
{ k=needsub(); /* get size */
if(k) j=array; /* 10 = array */
else j=pointer; /* 0 = pointer */
}
addglb(sname,j,typ,k); /* add symbol */
break;
}
if (match(",")==0) return; /* more ? */
}
}
/* */
/* Declare local variables (i.e.,define for use) */
/* Works just like "declglb" but modifies machine stack and adds sumbol table entry with appropriate */
/* stack offset to find it again */
/* */
/*
Modified to not update the stack on declaration until the
entire argument list has been parsed. See DDJ #67 in letters column.
*/
declloc(typ) /* type is cchar or cint */
int typ;
{
int k,j,newsp;
char sname[namesize];
/* Init the temp stack pointer */
newsp = sp;
while(1)
{
if(endst())break;
if(match("*"))
j=pointer;
else j=variable;
if(symname(sname)==0)
illname();
if(findloc(sname))
multidef(sname);
if(match("[")) {
k=needsub();
if(k)
{j=array;
if(typ==cint) k=k+k;
}
else {
j=pointer;
k=2;
}
}
else
if((typ==cchar)&&(j!=pointer))
k=1;
else k=2;
/*